package com.quan.site.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.quan.commons.core.MyBaseServiceImpl;
import com.quan.commons.utils.PageUtils;
import com.quan.site.commons.vo.SiteNavVo;
import com.quan.site.entity.SiteNav;
import com.quan.site.mapper.SiteNavMapper;
import com.quan.site.service.SiteNavService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
@Service
public class SiteNavServiceImpl extends MyBaseServiceImpl<SiteNavMapper, SiteNav> implements SiteNavService {

    @Autowired
    private SiteNavMapper mapper;

    @Override
    public SiteNavVo getInfo(Long id) {
        final SiteNav depart = super.getById(id);

        SiteNavVo bean = new SiteNavVo();
        BeanUtils.copyProperties(depart, bean);

        // 反推获取节点的父路径
        bean.setCascaderMenuPathVals(this.findPath(bean.getId()));

        return bean;
    }

    public boolean deleteByIds(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            this.recursiveDelete(id);
        }
        return true;
    }

    @Override
    public boolean removeById(Serializable id) {
        return this.recursiveDelete(id);
    }

    private boolean recursiveDelete(Serializable id) {
        QueryWrapper<SiteNav> queryWrapper = new QueryWrapper<SiteNav>();
        queryWrapper.eq("pid", id);

        List<SiteNav> child = super.list(queryWrapper);
        if (null != child) {
            for (SiteNav entity : child) {
                recursiveDelete(entity.getId());
            }
        }

        return super.removeById(id);
    }

    @Override
    public List<SiteNavVo> queryList(PageUtils pageUtils, SiteNavVo vo) {
        QueryWrapper<SiteNav> queryWrapper = new QueryWrapper<SiteNav>(vo);

        List<SiteNav> list = super.list(pageUtils, queryWrapper);
        List<SiteNavVo> collect = list.stream().map(item -> {
            SiteNavVo bean = new SiteNavVo();
            BeanUtils.copyProperties(item, bean);
            return bean;
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    public PageUtils queryPage(PageUtils pageUtils, SiteNavVo vo) {
        QueryWrapper<SiteNav> queryWrapper = new QueryWrapper<SiteNav>(vo);

        if (StringUtils.isNotBlank(vo.getKeyword())) {
            queryWrapper.and(w -> {
                w.like("name", vo.getKeyword());
            });
        }

        final IPage<SiteNav> page = super.selectPage(pageUtils, queryWrapper);

        PageUtils ps = new PageUtils(page);

        final List<SiteNav> records = page.getRecords();

        final List<SiteNav> collect = records.stream().map((item) -> {
            SiteNavVo bean = new SiteNavVo();
            BeanUtils.copyProperties(item, bean);
            return bean;
        }).collect(Collectors.toList());

        ps.setRecords(collect);
        return ps;
    }

    @Override
    public List<SiteNavVo> listWithTree(SiteNavVo vo) {

        final List<SiteNav> list = super.list(new QueryWrapper<>(vo));

        // 获取一级分类
        final List<SiteNavVo> collect = list.stream()
                .filter(category -> category.getPid() == 0)
                .map(item -> {
                    SiteNavVo bean = new SiteNavVo();
                    BeanUtils.copyProperties(item, bean);

                    // 获取子分类
                    bean.setChildren(getChildrens(bean, list));

                    return bean;
                }).sorted((menu, menu2) -> {
                    //2、菜单的排序
                    return (menu.getSort() == null ? 0 : menu.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
                }).collect(Collectors.toList());

        return collect;
    }

    //递归查找所有菜单的子菜单
    private List<SiteNav> getChildrens(SiteNavVo root, List<SiteNav> all) {

        List<SiteNav> children = all.stream().filter(categoryEntity -> {
            return categoryEntity.getPid().equals(root.getId());
        }).map(item -> {
            SiteNavVo bean = new SiteNavVo();
            BeanUtils.copyProperties(item, bean);
            //1、找到子菜单(递归)
            bean.setChildren(getChildrens(bean, all));
            return bean;
        }).sorted((menu, menu2) -> {
            //2、菜单的排序
            return (menu.getSort() == null ? 0 : menu.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
        }).collect(Collectors.toList());

        return children;

    }


    @Override
    public Long[] findPath(Long menuId) {

        List<Long> paths = new ArrayList<>();

        //递归查询是否还有父节点
        List<Long> parentPath = findParentPath(menuId, paths);

        //进行一个逆序排列
        Collections.reverse(parentPath);

        return (Long[]) parentPath.toArray(new Long[parentPath.size()]);
    }

    private List<Long> findParentPath(Long menuId, List<Long> paths) {
        //1、收集当前节点id
        paths.add(menuId);

        //根据当前分类id查询信息
        SiteNav menu = this.getById(menuId);
        //如果当前不是父分类
        if (menu.getPid() != 0) {
            findParentPath(menu.getPid(), paths);
        }
        return paths;
    }
}